home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995…tember: Reference Library / Dev.CD Sep 95 RL / Dev.CD Sep 95 RL.toast / mac / Technical Documentation / develop / develop Issue 20 code / Scripting the Finder / Finder Tricks / Listings.cp < prev    next >
Encoding:
Text File  |  1994-10-04  |  10.8 KB  |  343 lines  |  [TEXT/MMCC]

  1. //========================================================================================
  2. // Program Listings from "Scripting the Finder from your own Application"
  3. // develop Issue 20
  4. // Greg Anderson
  5. //========================================================================================
  6. #include "AppleEventUtilities.h"
  7. #include "AERegistry.h"
  8. #include "AEObjects.h"
  9. #include "FinderRegistry.h"
  10. #include "Exceptions.h"
  11.  
  12.  
  13.  
  14. //----------------------------------------------------------------------------------------
  15. // Listing 1 
  16. //
  17. // This function gets the address of the Finder running on this machine.  It walks the
  18. // process list rather than just building an address for the Finder's creator type,
  19. // 'MACS', because there are other applications whose creator type is 'MACS'.
  20. //----------------------------------------------------------------------------------------
  21. TDescriptor GetAddressOfFinder()
  22. {
  23.     ProcessSerialNumber        psn;
  24.     ProcessInfoRec            theProc;
  25.     TDescriptor                finderAddressDescriptor;
  26.         
  27.     psn.highLongOfPSN = 0;
  28.     psn.lowLongOfPSN = kNoProcess;
  29.     
  30.     //
  31.     // Initialize fields in the ProcessInfoRec,
  32.     // or we'll have memory hits in random locations
  33.     //
  34.     theProc.processInfoLength = sizeof( ProcessInfoRec );
  35.     theProc.processName = nil;
  36.     theProc.processAppSpec = nil;
  37.     theProc.processLocation = nil;
  38.     
  39.     while(true)
  40.     {
  41.         FailErr(GetNextProcess(&psn));
  42.         if( (psn.highLongOfPSN == 0) && (psn.lowLongOfPSN == kNoProcess) )
  43.             Throw(procNotFound);
  44.         
  45.         FailErr(GetProcessInformation(&psn, &theProc));
  46.         if( (theProc.processType == 'FNDR' ) && (theProc.processSignature == 'MACS') )
  47.             break;
  48.     }
  49.     finderAddressDescriptor.MakeProcessSerialNumber(psn);
  50.     
  51.     return finderAddressDescriptor;
  52. } // GetAddressOfFinder 
  53.  
  54. //----------------------------------------------------------------------------------------
  55. // Listing 2
  56. //
  57. // This function returns the items that are currently selected in the Finder.
  58. //----------------------------------------------------------------------------------------
  59. TDescriptor GetFinderSelection(DescType desiredType)
  60. {
  61.     TAEvent ae;
  62.     OSErr err = noErr;
  63.     
  64.         //
  65.         // Get the address of the Finder and make a "Set Data" event
  66.         //
  67.         TDescriptor target = GetAddressOfFinder();
  68.         ae.MakeAppleEvent(kAECoreSuite, kAEGetData, target);
  69.         target.Dispose();
  70.         
  71.         //
  72.         // Make an object specifier for the property we want to set,
  73.         // and put it into the direct object of our event
  74.         //
  75.         TDescriptor directObjectSpecifier;
  76.         TDescriptor keyData;
  77.         TDescriptor nullDescriptor;
  78.  
  79.         keyData.MakeDescType(pSelection);
  80.         directObjectSpecifier.MakeObjectSpecifier(    cProperty,
  81.                                             nullDescriptor,
  82.                                             formPropertyID,
  83.                                             keyData,
  84.                                             true);
  85.         ae.PutDescriptor(keyDirectObject, directObjectSpecifier);
  86.         directObjectSpecifier.Dispose();
  87.         
  88.         //
  89.         // Request FSSpecs back from the Get Data event.
  90.         //
  91.         // The Object Support Library requires that the
  92.         // requested data type be stored in a list of types,
  93.         // so we coerce the 'typeType' descriptor into a list
  94.         // of one descriptor.  The Finder does not require
  95.         // this, but some other applications might, since it
  96.         // is part of the OSL spec.
  97.         //
  98.         TDescriptor dataDescriptor;
  99.  
  100.         dataDescriptor.MakeDescType(typeAlias);
  101.         dataDescriptor.CoerceInPlace(typeAEList);
  102.         ae.PutDescriptor(keyAERequestedType, dataDescriptor);
  103.         dataDescriptor.Dispose();
  104.         
  105.         //
  106.         // It is generally a bad idea to use kAEWaitReply,
  107.         // because it prevents your application from processing
  108.         // other events.  There are a number of potential solutions:
  109.         //
  110.         //        Use kAEQueueReply, and process the reply when it is
  111.         //        returned from WaitNextEvent.  The disadvantage is that
  112.         //        the processing of the reply must be done separately
  113.         //        from the code that sets up to do the send
  114.         //
  115.         //        Provide a filter proc to AESend that processes
  116.         //        events while your application is waiting for the reply.
  117.         //        The disadvantage of doing this is that the event
  118.         //        handling of your application is complicated, and
  119.         //        may become nested if events need to be sent to
  120.         //        process an incoming message
  121.         //
  122.         //        Pass kImmediateTimeout as the timeout value for
  123.         //        AESend.  When the reply event is accessed, an
  124.         //        error is returned if the reply has not yet arrived.
  125.         //        This method is best employeed in conjunction with
  126.         //        a threads package, so that the thread that sends
  127.         //        the message can block until the reply arrives.
  128.         //        See the article on Futures by Michael Gough in
  129.         //        d e v e l o p  issue #7.
  130.         //
  131.         TAEvent reply;
  132.         ae.Send(&reply, kAEWaitReply);
  133.         
  134.         //
  135.         // Extract the result from the reply
  136.         //    
  137.         TDescriptor selectedItems = reply.GetDescriptor(keyAEResult);
  138.         reply.Dispose();
  139.         ae.Dispose();
  140.     
  141.     return selectedItems;
  142. } // GetFinderSelection
  143.  
  144. //----------------------------------------------------------------------------------------
  145. // Listing 3
  146. //
  147. // This function returns the owner (folder, file, disk or trash) of the frontmost window.
  148. //----------------------------------------------------------------------------------------
  149. TDescriptor Listing3()
  150. {
  151.     TAEvent ae;
  152.     
  153.     TDescriptor target = GetAddressOfFinder();
  154.     ae.MakeAppleEvent(kAECoreSuite, kAEGetData, target);
  155.     target.Dispose();
  156.     
  157.     TDescriptor directObjectSpecifier;
  158.     TDescriptor frontWindowSpecifier;
  159.     TDescriptor keyData;
  160.     TDescriptor nullDescriptor;
  161.     
  162.     keyData.MakeLong(1);
  163.     frontWindowSpecifier.MakeObjectSpecifier(cWindow, nullDescriptor, formAbsolutePosition, keyData, true);
  164.     keyData.MakeDescType(cObject);
  165.     directObjectSpecifier.MakeObjectSpecifier(cProperty, frontWindowSpecifier, formPropertyID, keyData, true);
  166.     ae.PutDescriptor(keyDirectObject, directObjectSpecifier);
  167.     directObjectSpecifier.Dispose();
  168.     
  169.     TDescriptor dataDescriptor;
  170.  
  171.     dataDescriptor.MakeDescType(typeAlias);
  172.     dataDescriptor.CoerceInPlace(typeAEList);
  173.     ae.PutDescriptor(keyAERequestedType, dataDescriptor);
  174.     dataDescriptor.Dispose();
  175.  
  176.     TAEvent reply;
  177.     ae.Send(&reply, kAEWaitReply);
  178.     
  179.     //
  180.     // Extract the result from the reply
  181.     //    
  182.     TDescriptor frontWindowOwner = reply.GetDescriptor(keyAEResult);
  183.     reply.Dispose();
  184.     ae.Dispose();
  185.     
  186.     return frontWindowOwner;
  187. }
  188.  
  189.  
  190. //----------------------------------------------------------------------------------------
  191. // Listing 4
  192. //
  193. // This function deletes the custom icon from every item (file or folder) currently
  194. // selected in the Finder.
  195. //----------------------------------------------------------------------------------------
  196. void Listing4()
  197. {
  198.     TAEvent ae;
  199.     
  200.     TDescriptor target = GetAddressOfFinder();
  201.     ae.MakeAppleEvent(kAECoreSuite, kAESetData, target);
  202.     target.Dispose();
  203.     
  204.     TDescriptor directObjectSpecifier;
  205.     TDescriptor selectionSpecifier;
  206.     TDescriptor keyData;
  207.     TDescriptor nullDescriptor;
  208.     
  209.     keyData.MakeDescType(pSelection);
  210.     selectionSpecifier.MakeObjectSpecifier(cProperty, nullDescriptor, formPropertyID, keyData, true);
  211.     keyData.MakeDescType(pIconBitmap);
  212.     directObjectSpecifier.MakeObjectSpecifier(cProperty, selectionSpecifier, formPropertyID, keyData, true);
  213.     ae.PutDescriptor(keyDirectObject, directObjectSpecifier);
  214.     directObjectSpecifier.Dispose();
  215.     
  216.     TDescriptor emptyList;
  217.  
  218.     emptyList.MakeEmptyList();
  219.     ae.PutDescriptor(keyAEData, emptyList);
  220.     emptyList.Dispose();
  221.  
  222.     TAEvent reply;
  223.     ae.Send(&reply, kAENoReply);
  224.     ae.Dispose();
  225. }
  226.  
  227. //----------------------------------------------------------------------------------------
  228. // Listing 5
  229. //
  230. // This function makes sure that the Finder's representation for the specified
  231. // container is up-to-date with what is on disk.  It is useful to tell the Finder
  232. // to do this whenever your application writes into a given folder; this will make
  233. // sure that the Finder always re-sorts the window so that the modification date
  234. // of the item is correct (to name one example).
  235. //----------------------------------------------------------------------------------------
  236. void UpdateFinderContainer(FSSpec& changedContainer)
  237. {
  238.     TAEvent ae;
  239.     
  240.     TDescriptor target = GetAddressOfFinder();
  241.     ae.MakeAppleEvent(kAEFinderSuite, kAEUpdate, target);
  242.     target.Dispose();
  243.     
  244.     TDescriptor directObjectSpecifier;
  245.     
  246.     directObjectSpecifier.MakeFSS(changedContainer);
  247.     ae.PutDescriptor(keyDirectObject, directObjectSpecifier);
  248.     directObjectSpecifier.Dispose();
  249.     
  250.     TAEvent reply;
  251.     ae.Send(&reply, kAENoReply);
  252.     ae.Dispose();
  253. }
  254.  
  255.  
  256. //----------------------------------------------------------------------------------------
  257. // Listing 6
  258. //
  259. // This listing shares every folder currently selected in the Finder.
  260. //----------------------------------------------------------------------------------------
  261. void Listing6()
  262. {
  263.     TAEvent ae;
  264.     
  265.     TDescriptor target = GetAddressOfFinder();
  266.     ae.MakeAppleEvent(kAECoreSuite, kAESetData, target);
  267.     target.Dispose();
  268.     
  269.     TDescriptor selectionSpecifier;
  270.     TDescriptor keyData;
  271.     TDescriptor nullDescriptor;
  272.     
  273.     keyData.MakeDescType(pSelection);
  274.     selectionSpecifier.MakeObjectSpecifier(cProperty, nullDescriptor, formPropertyID, keyData, true);
  275.  
  276.     TDescriptor everySpecifier;
  277.     keyData.MakeOrdinal(kAEAll);
  278.     everySpecifier.MakeObjectSpecifier(cFolder, selectionSpecifier, formAbsolutePosition, keyData, true);
  279.     
  280.     TDescriptor directObjectSpecifier;
  281.     keyData.MakeDescType(pSharing);
  282.     directObjectSpecifier.MakeObjectSpecifier(cProperty, everySpecifier, formPropertyID, keyData, true);
  283.     ae.PutDescriptor(keyDirectObject, directObjectSpecifier);
  284.     directObjectSpecifier.Dispose();
  285.     
  286.     TDescriptor sharedSetting;
  287.  
  288.     sharedSetting.MakeBoolean(true);
  289.     ae.PutDescriptor(keyAEData, sharedSetting);
  290.     sharedSetting.Dispose();
  291.  
  292.     TAEvent reply;
  293.     ae.Send(&reply, kAENoReply);
  294.     ae.Dispose();
  295. }
  296.  
  297. //----------------------------------------------------------------------------------------
  298. // Listing 7
  299. //
  300. // This listing moves the item named "x" on the desktop into the preferences folder
  301. // and sets its location to (10, 10).  If the preferences folder is open, this location
  302. // will be in local coordinates.  If the window is not open, then the coordinates
  303. // will be in the same coordinate space written to disk in the Finder Info field.
  304. //----------------------------------------------------------------------------------------
  305. void Listing7()
  306. {
  307.     TAEvent ae;
  308.     
  309.     TDescriptor target = GetAddressOfFinder();
  310.     ae.MakeAppleEvent(kAECoreSuite, kAEMove, target);
  311.     target.Dispose();
  312.  
  313.     TDescriptor directObjectSpecifier;
  314.     TDescriptor keyData;
  315.     TDescriptor nullDescriptor;
  316.     
  317.     keyData.MakeString("\px");
  318.     directObjectSpecifier.MakeObjectSpecifier(cObject, nullDescriptor, formName, keyData, true);
  319.     ae.PutDescriptor(keyDirectObject, directObjectSpecifier);
  320.     directObjectSpecifier.Dispose();
  321.  
  322.     TDescriptor preferencesSpecifier;
  323.     
  324.     keyData.MakeDescType(pPreferencesFolder);
  325.     preferencesSpecifier.MakeObjectSpecifier(cProperty, nullDescriptor, formPropertyID, keyData, true);
  326.     ae.PutDescriptor(keyAEInsertHere, preferencesSpecifier);
  327.     
  328.     Point destinationPosition;
  329.     destinationPosition.h = 10;
  330.     destinationPosition.v = 10;
  331.     
  332.     keyData.MakePoint(destinationPosition);
  333.     keyData.CoerceInPlace(typeAEList);
  334.     ae.PutDescriptor(keyLocalPositionList, keyData);
  335.     keyData.Dispose();
  336.  
  337.     TAEvent reply;
  338.     ae.Send(&reply, kAENoReply);
  339.  
  340.     ae.Dispose();
  341. }
  342.  
  343.